/**
 * User Controller.
 */
class UserController {

    def authenticateService

    // the delete, save and update actions only accept POST requests
    def allowedMethods = [delete: 'POST', save: 'POST', update: 'POST']

    def index = {
        redirect(action: list, params: params)
    }

    def list = {
        if (!params.max) {
            params.max = 10
        }
        if (authenticateService.ifAllGranted("ROLE_ADMIN")) {
            return [personList: User.list(params)]
        } else if (authenticateService.ifAllGranted("ROLE_USER")) {
            redirect(action: show)
        }

    }

    def show = {
        if (authenticateService.ifAllGranted("ROLE_ADMIN")) {
            return [person: User.get(params.id)]
        } else if (authenticateService.ifAllGranted("ROLE_USER")) {
            return [person: User.get(authenticateService.userDomain().id)]
        }

    }

    /**
      * Person delete action. Before removing an existing person,
      * he should be removed from those authorities which he is involved.
      */
    def delete = {

        def person = User.get(params.id)

        if (person) {
            def authPrincipal = authenticateService.principal()
            //avoid self-delete if the logged-in user is an admin
            if (!(authPrincipal instanceof String) && authPrincipal.username == person.username) {
                flash.message = "You can not delete yourself, please login as another admin and try again"
                redirect(action: show)
            }
            else {
                //first, delete this person from People_Authorities table.
                Role.findAll().each {it.removeFromPeople(person)}
                person.delete()
                flash.message = "User ${params.id} deleted."
            }
        }
        else {
            flash.message = "User not found with id ${params.id}"
        }

        redirect(action: list)
    }

    def edit = {

        def person = User.get(params.id)
        if (!person) {
            flash.message = "User not found with id ${params.id}"
            redirect(action: list)
            return
        }

        [person: person, authorityList: Role.list(params)]
    }

    /**
      * Person update action.
      */
    def update = {

        def person = User.get(params.id)
        if (!person) {
            flash.message = "User not found with id ${params.id}"
            redirect(action: edit, id: params.id)
            return
        }

        def oldPassword = person.passwd
        person.properties = params
        if (!params.passwd.equals(oldPassword)) {
            person.passwd = authenticateService.passwordEncoder(params.passwd)
        }


        if (person.save()) {
            if (authenticateService.ifAllGranted("ROLE_ADMIN")) {
                Role.findAll().each {it.removeFromPeople(person)}
                addRoles(person)
            }
            redirect(action: show, id: person.id)
        }
        else {
            render(view: 'edit', model: [person: person])
        }
    }

    def create = {
        def person = new User()
        person.properties = params
        [person: person, authorityList: Role.list(params)]
    }

    /**
      * Person save action.
      */
    def save = {
        def person = new User()
        person.properties = params
        person.passwd = authenticateService.passwordEncoder(params.passwd)
        if (person.save()) {
            addRoles(person)
            redirect(action: show, id: person.id)
        }
        else {
            render(view: 'create', model: [authorityList: Role.list(params), person: person])
        }
    }

    private void addRoles(person) {
        for (String key in params.keySet()) {
            if (key.contains('ROLE') && 'on' == params.get(key)) {
                Role.findByAuthority(key).addToPeople(person)
            }
        }
    }
}
